﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.Diagnostics;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Authorization.Users;
using Abp.AutoMapper;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Microsoft.AspNet.Identity;
using MyCompanyName.AbpZeroTemplate.Authorization.Dto;
using MyCompanyName.AbpZeroTemplate.Authorization.Roles;
using MyCompanyName.AbpZeroTemplate.Authorization.Users.Dto;
using MyCompanyName.AbpZeroTemplate.Authorization.Users.Exporting;
using MyCompanyName.AbpZeroTemplate.Dto;
using Abp.Domain.Repositories;
using MyCompanyName.AbpZeroTemplate.Prm.Admin;
using MyCompanyName.AbpZeroTemplate.Prm.Admin.Dto;
using System.Web;
using System.IO;
using Abp.Organizations;
using MyCompanyName.AbpZeroTemplate.Prm.Project;
using MyCompanyName.AbpZeroTemplate.Prm.Inquiry;
using System;

namespace MyCompanyName.AbpZeroTemplate.Authorization.Users
{
    //[AbpAuthorize(AppPermissions.Pages_Administration_Users)]
    public class UserAppService : AbpZeroTemplateAppServiceBase, IUserAppService
    {
        private readonly RoleManager _roleManager;
        private readonly IUserEmailer _userEmailer;
        private readonly IUserListExcelExporter _userListExcelExporter;
        private readonly IRepository<Business, int> businessRepository;
        private readonly IRepository<RdCenter, int> rdCenterRepository;
        private readonly IRepository<Quan, int> quanRepository;
        private readonly IRepository<UserQuan, int> userQuanRepository;
        private readonly IRepository<Role, int> roleRepository;
        private readonly IRepository<Laboratory, int> laboratoryRepository;

        private readonly IRepository<SystemDic, int> sysDicRepository;


        private readonly IRepository<MyCompanyName.AbpZeroTemplate.Prm.Project.ProjectInfo, int> projectRepository;
        private readonly IRepository<MyCompanyName.AbpZeroTemplate.Prm.Inquiry.Inquiry, int> inquiryRepository;

        private readonly IRepository<OrganizationUnit, long> organizationUnitRepository;
        private readonly IRepository<User, long> userRepository;
        private readonly IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository;


        public UserAppService(
            RoleManager roleManager,
            IUserEmailer userEmailer,
            IUserListExcelExporter userListExcelExporter,
            IRepository<Business, int> _businessRepository,
            IRepository<RdCenter, int> _rdCenterRepository,
            IRepository<Laboratory, int> _laboratoryRepository,
            IRepository<OrganizationUnit, long> _organizationUnitRepository,
            IRepository<UserOrganizationUnit, long> _userOrganizationUnitRepository,
            IRepository<User, long> _userRepository,
            IRepository<ProjectInfo, int> _projectRepository,
            IRepository<Inquiry, int> _inquiryRepository,
             IRepository<Quan, int> _quanRepository,
            IRepository<UserQuan, int> _userQuanRepository,
            IRepository<Role, int> _roleRepository,
            IRepository<SystemDic, int> _sysDicRepository
            )
        {
            _roleManager = roleManager;
            _userEmailer = userEmailer;
            _userListExcelExporter = userListExcelExporter;
            rdCenterRepository = _rdCenterRepository;
            laboratoryRepository = _laboratoryRepository;
            businessRepository = _businessRepository;
            organizationUnitRepository = _organizationUnitRepository;
            userOrganizationUnitRepository = _userOrganizationUnitRepository;
            userRepository = _userRepository;
            projectRepository = _projectRepository;
            inquiryRepository = _inquiryRepository;
            quanRepository = _quanRepository;
            userQuanRepository = _userQuanRepository;
            roleRepository = _roleRepository;
            sysDicRepository = _sysDicRepository;
        }

        public async Task<PagedResultOutput<UserListDto>> GetPagedUsers(GetUsersInput input)
        {
            var query = UserManager.Users
                .Include(u => u.Roles)
                .WhereIf(
                    !input.Filter.IsNullOrWhiteSpace(),
                    u =>
                        u.Name.Contains(input.Filter) ||
                        u.Surname.Contains(input.Filter) ||
                        u.UserName.Contains(input.Filter) ||
                        u.EmailAddress.Contains(input.Filter)
                );

            var userCount = await query.CountAsync();
            var users = await query
                .OrderBy(input.Sorting)
                .PageBy(input)
                .ToListAsync();

            var userListDtos = users.MapTo<List<UserListDto>>();
            await FillRoleNames(userListDtos);

            return new PagedResultOutput<UserListDto>(
                userCount,
                userListDtos
                );
        }


        //public async Task<PagedResultOutput<UserListDto>> GetUsers(string Filter, string Sorting, int start, int limit)
        //{
        //    var query = UserManager.Users
        //        .Include(u => u.Roles)
        //        .WhereIf(
        //            !Filter.IsNullOrWhiteSpace(),
        //            u =>
        //                u.Name.Contains(Filter) ||
        //                u.Surname.Contains(Filter) ||
        //                u.UserName.Contains(Filter) ||
        //                u.EmailAddress.Contains(Filter)
        //        );

        //    var userCount = await query.CountAsync();
        //    var users = await query
        //        .OrderBy(Sorting)
        //        .Skip(start)
        //        .Take(limit)
        //        .ToListAsync();

        //    var userListDtos = users.MapTo<List<UserListDto>>();
        //    await FillRoleNames(userListDtos);

        //    return new PagedResultOutput<UserListDto>(
        //        userCount,
        //        userListDtos
        //        );
        //}

        public async Task<FileDto> GetUsersToExcel()
        {
            var users = await UserManager.Users.Include(u => u.Roles).ToListAsync();
            var userListDtos = users.MapTo<List<UserListDto>>();
            await FillRoleNames(userListDtos);

            return _userListExcelExporter.ExportToFile(userListDtos);
        }

        // [AbpAuthorize(AppPermissions.Pages_Administration_Users_Create, AppPermissions.Pages_Administration_Users_Edit)]
        public async Task<GetUserForEditOutput> GetUserForEdit(NullableIdInput<long> input)
        {
            var userRoleDtos = (await _roleManager.Roles
                .OrderBy(r => r.DisplayName)
                .Select(r => new UserRoleDto
                             {
                                 RoleId = r.Id,
                                 RoleName = r.Name,
                                 RoleDisplayName = r.DisplayName
                             })
                .ToArrayAsync());

            var output = new GetUserForEditOutput
            {
                Roles = userRoleDtos
            };

            var centers = rdCenterRepository.GetAll();

            var bus = businessRepository.GetAll();
            output.Business = bus.MapTo<List<GetBusinessOutPut>>();

            var laboratory = laboratoryRepository.GetAll();

            if (!input.Id.HasValue)
            {
                //Creating a new user
                output.User = new UserEditDto { IsActive = true, ShouldChangePasswordOnNextLogin = true };

                foreach (var defaultRole in await _roleManager.Roles.Where(r => r.IsDefault).ToListAsync())
                {
                    var defaultUserRole = userRoleDtos.FirstOrDefault(ur => ur.RoleName == defaultRole.Name);
                    if (defaultUserRole != null)
                    {
                        defaultUserRole.IsAssigned = true;
                    }
                }
            }
            else
            {
                //Editing an existing user
                var user = await UserManager.GetUserByIdAsync(input.Id.Value);

                output.User = user.MapTo<UserEditDto>();
                if (user.BusinessId > 0)
                {
                    var _bus = businessRepository.Get(user.BusinessId);
                    output.BusinessName = _bus.Name;
                }
                if (user.RdCenterId > 0)
                {
                    var _center = rdCenterRepository.Get(user.RdCenterId);
                    output.RdCenterName = _center.Name;
                }
                if (user.LaboratoryId > 0)
                {
                    var _lab = laboratoryRepository.Get(user.LaboratoryId);
                    output.LaboratoryName = _lab.Name;
                }

                output.ProfilePictureId = user.ProfilePictureId;

                foreach (var userRoleDto in userRoleDtos)
                {
                    userRoleDto.IsAssigned = await UserManager.IsInRoleAsync(input.Id.Value, userRoleDto.RoleName);
                }

                laboratory = laboratory.Where(x => x.RdCenterId == user.RdCenterId);
                centers = centers.Where(x => x.BusinessId == user.BusinessId);
            }
            output.RdCenter = centers.MapTo<List<GetRdCenterOutPut>>();
            output.Laboratory = laboratory.MapTo<List<GetLaboratoryOutPut>>();
            return output;
        }

        //[AbpAuthorize(AppPermissions.Pages_Administration_Users_ChangePermissions)]
        public async Task<GetUserPermissionsForEditOutput> GetUserPermissionsForEdit(IdInput<long> input)
        {
            var user = await UserManager.GetUserByIdAsync(input.Id);
            var permissions = PermissionManager.GetAllPermissions();
            var grantedPermissions = await UserManager.GetGrantedPermissionsAsync(user);

            return new GetUserPermissionsForEditOutput
                   {
                       Permissions = permissions.MapTo<List<FlatPermissionDto>>().OrderBy(p => p.DisplayName).ToList(),
                       GrantedPermissionNames = grantedPermissions.Select(p => p.Name).ToList()
                   };
        }



        //[AbpAuthorize(AppPermissions.Pages_Administration_Users_ChangePermissions)]
        public async Task ResetUserSpecificPermissions(IdInput<long> input)
        {
            var user = await UserManager.GetUserByIdAsync(input.Id);
            await UserManager.ResetAllPermissionsAsync(user);
        }

        // [AbpAuthorize(AppPermissions.Pages_Administration_Users_ChangePermissions)]
        public async Task UpdateUserPermissions(UpdateUserPermissionsInput input)
        {
            var user = await UserManager.GetUserByIdAsync(input.Id);
            var grantedPermissions = PermissionManager.GetPermissionsFromNamesByValidating(input.GrantedPermissionNames);
            await UserManager.SetGrantedPermissionsAsync(user, grantedPermissions);
        }

        public async Task CreateOrUpdateUser(CreateOrUpdateUserInput input)
        {
            if (input.User.Id.HasValue)
            {
                await UpdateUserAsync(input);
            }
            else
            {
                await CreateUserAsync(input);
            }
        }

        // [AbpAuthorize(AppPermissions.Pages_Administration_Users_Delete)]
        public async Task DeleteUser(IdInput<long> input)
        {
            var user = await UserManager.GetUserByIdAsync(input.Id);
            CheckErrors(await UserManager.DeleteAsync(user));
        }

        //[AbpAuthorize(AppPermissions.Pages_Administration_Users_Edit)]
        protected virtual async Task UpdateUserAsync(CreateOrUpdateUserInput input)
        {
            Debug.Assert(input.User.Id != null, "input.User.Id should be set.");

            var user = await UserManager.FindByIdAsync(input.User.Id.Value);

            //Update user properties
            //input.User.MapTo(user); //Passwords is not mapped (see mapping configuration)

            //if (!input.User.Password.IsNullOrEmpty())
            //{
            //    CheckErrors(await UserManager.ChangePasswordAsync(user, input.User.Password));
            //}

            user.UserName = input.User.UserName;
            user.Name = input.User.Name;
            user.Surname = input.User.Name;
            user.EmailAddress = input.User.EmailAddress;
            user.BusinessId = input.User.BusinessId;
            user.RdCenterId = input.User.RdCenterId;
            user.LaboratoryId = input.User.LaboratoryId;
            user.IsActive = input.User.IsActive;

            CheckErrors(await UserManager.UpdateAsync(user));

            //Update roles
            CheckErrors(await UserManager.SetRoles(user, input.AssignedRoleNames));

            userQuanRepository.Delete(m => m.UserId == input.User.Id);
            List<int> adds = new List<int>();
            foreach (var item in input.Quans)
            {
                if (!input.Quans.Any(x => x.Key == item.Value))
                {
                    adds.Add(item.Key);
                }
            }

            foreach (var item in adds)
            {
                var quan = quanRepository.Get(item);
                await userQuanRepository.InsertAsync(new UserQuan()
                {
                    QuanId = item,
                    UserId = (long)input.User.Id,
                    QuanCode = quan.Code
                });
            }

            //if (input.SendActivationEmail)
            //{
            //    user.SetNewEmailConfirmationCode();
            //    await _userEmailer.SendEmailActivationLinkAsync(user, input.User.Password);
            //}
        }

        //[AbpAuthorize(AppPermissions.Pages_Administration_Users_Create)]
        protected virtual async Task CreateUserAsync(CreateOrUpdateUserInput input)
        {
            var user = input.User.MapTo<User>(); //Passwords is not mapped (see mapping configuration)
            user.TenantId = AbpSession.TenantId;

            if (!input.User.Password.IsNullOrEmpty())
            {
                CheckErrors(await UserManager.PasswordValidator.ValidateAsync(input.User.Password));
            }
            else
            {
                input.User.Password = User.CreateRandomPassword();
            }

            user.Password = new PasswordHasher().HashPassword(input.User.Password);
            user.ShouldChangePasswordOnNextLogin = input.User.ShouldChangePasswordOnNextLogin;

            user.Roles = new Collection<UserRole>();
            foreach (var roleName in input.AssignedRoleNames)
            {
                var role = await _roleManager.GetRoleByNameAsync(roleName);
                user.Roles.Add(new UserRole { RoleId = role.Id });
            }

            CheckErrors(await UserManager.CreateAsync(user));
            await CurrentUnitOfWork.SaveChangesAsync(); //To get new user's Id.


            List<int> adds = new List<int>();
            foreach (var item in input.Quans)
            {
                if (!input.Quans.Any(x => x.Key == item.Value))
                {
                    adds.Add(item.Key);
                }
            }

            foreach (var item in adds)
            {
                var quan = quanRepository.Get(item);
                await userQuanRepository.InsertAsync(new UserQuan()
                {
                    QuanId = item,
                    UserId = user.Id,
                    QuanCode = quan.Code
                });
            }

            if (input.SendActivationEmail)
            {
                user.SetNewEmailConfirmationCode();
                await _userEmailer.SendEmailActivationLinkAsync(user, input.User.Password);
            }
        }

        private async Task FillRoleNames(List<UserListDto> userListDtos)
        {
            /* This method is optimized to fill role names to given list. */

            var distinctRoleIds = (
                from userListDto in userListDtos
                from userListRoleDto in userListDto.Roles
                select userListRoleDto.RoleId
                ).Distinct();

            var roleNames = new Dictionary<int, string>();
            foreach (var roleId in distinctRoleIds)
            {
                roleNames[roleId] = (await _roleManager.GetRoleByIdAsync(roleId)).DisplayName;
            }

            foreach (var userListDto in userListDtos)
            {
                foreach (var userListRoleDto in userListDto.Roles)
                {
                    userListRoleDto.RoleName = roleNames[userListRoleDto.RoleId];
                }

                userListDto.Roles = userListDto.Roles.OrderBy(r => r.RoleName).ToList();
            }


            var userQuan = userQuanRepository.GetAll().ToList();
            var quans = quanRepository.GetAll().ToList();
            foreach (var item in userListDtos)
            {
                var quanIds = userQuan.Where(x => x.UserId == item.Id).Select(x => x.QuanId).ToList();
                if (quanIds.Count > 0)
                {
                    item.quan = string.Join(",", quans.Where(x => quanIds.Contains(x.Id)).Select(x => x.Name));
                }
                else
                {
                    item.quan = "";
                }
            }
        }


        public List<UserListDto> GetUsers(string name)
        {

            var query = UserManager.Users
                .WhereIf(true,
                    u =>
                        u.Name.Contains(name) ||
                        u.Surname.Contains(name) ||
                        u.UserName.Contains(name) ||
                        u.EmailAddress.Contains(name)
                );



            var userListDtos = query.MapTo<List<UserListDto>>();

            return userListDtos;
        }

        public List<dynamic> GetAllCustomers()
        {
            var expectCustomer = sysDicRepository.GetAll().Where(x => x.DictKey == DictKey.排除客户列表).Select(x => x.DisplayName).ToList();
            var aa = sysDicRepository.GetAll().Where(x => x.DictKey == DictKey.客户列表).Select(x => x.DisplayName).ToList();





            List<dynamic> lst = new List<dynamic>();




            List<Status> projectDoingStatus = new List<Status>(){
          Status.进行中,
          Status.暂停,
          Status.准备
         };
            var doingProjects = projectRepository.GetAll().Where(x => projectDoingStatus.Contains(x.Status)).ToList();

            foreach (var item in aa)
            {
                if (expectCustomer.Contains(item))
                {
                    continue;
                }
                lst.Add(
                    new
                    {
                        Id = System.Guid.NewGuid(),
                        name = item,
                        doingCount = doingProjects.Where(x => x.Customer == item).Count()
                    });
            }
            return lst;
        }
        public List<dynamic> GetCustomers(string name)
        {
            List<dynamic> lst = new List<dynamic>();

            var expectCustomer = sysDicRepository.GetAll().Where(x => x.DictKey == DictKey.排除客户列表).Select(x => x.DisplayName).ToList();
            var aa = sysDicRepository.GetAll().Where(x => x.DictKey == DictKey.客户列表).Select(x => x.DisplayName).ToList();
            if (!string.IsNullOrWhiteSpace(name) && !name.Equals("*"))
            {
                aa = aa.Where(x => x.Contains(name)).ToList();
            }
            int index = 1;
            foreach (var item in aa)
            {
                if (expectCustomer.Contains(item))
                {
                    continue;
                }
                lst.Add(
                    new
                    {
                        Id = index++,
                        name = item
                    });
            }

            return lst;
        }

        public string GetUserCompany(long userId)
        {
            string companyLevel = "";
            var user = UserManager.Users.Where(x => x.Id == userId).FirstOrDefault();
            List<string> level = new List<string>();
            if (user != null)
            {
                if (user.BusinessId > 0)
                {
                    var _bus = businessRepository.Get(user.BusinessId);
                    level.Add(_bus.Name);
                }
                if (user.RdCenterId > 0)
                {
                    var _center = rdCenterRepository.Get(user.RdCenterId);
                    level.Add(_center.Name);
                }
                if (user.LaboratoryId > 0)
                {
                    var _lab = laboratoryRepository.Get(user.LaboratoryId);
                    level.Add(_lab.Name);
                }
            }

            return string.Join(">>", level);
        }

        public string GetUserName(long userId)
        {
            var u = UserManager.Users.Where(x => x.Id == userId).FirstOrDefault();
            if (u != null)
                return u.Name;
            else
                return "";
        }

        public async Task<List<UserListDto>> GetAll()
        {
            var query = await UserManager.Users.OrderBy(x => x.Name).ToListAsync();
            var userListDtos = query.MapTo<List<UserListDto>>();
            foreach (var item in userListDtos)
            {

                if (item.LaboratoryId > 0)
                {
                    var l = laboratoryRepository.GetAll().Where(x => x.Id == item.LaboratoryId).FirstOrDefault();
                    if (l != null)
                    {
                        item.LaboratoryName = l.Name;
                    }
                    else
                    {
                        var u = UserManager.Users.Where(x => x.Id == item.Id).Single();
                        u.LaboratoryId = 0;
                        item.LaboratoryId = 0;
                        item.LaboratoryName = "";
                    }
                }
                else
                {
                    item.LaboratoryId = 0;
                    item.LaboratoryName = "";
                }

                if (item.BusinessId > 0)
                {
                    var b = businessRepository.GetAll().Where(x => x.Id == item.BusinessId).FirstOrDefault();
                    if (b == null)
                    {
                        var u = UserManager.Users.Where(x => x.Id == item.Id).Single();
                        u.BusinessId = 0;


                        item.BusinessId = 0;
                        item.BusinessName = "";
                    }
                    else
                    {
                        item.BusinessName = b.Name;
                    }
                }
                else
                {
                    item.BusinessId = 0;
                    item.BusinessName = "";
                }


                if (item.RdCenterId > 0)
                {
                    var r = rdCenterRepository.GetAll().Where(x => x.Id == item.RdCenterId).FirstOrDefault();
                    if (r == null)
                    {
                        var u = UserManager.Users.Where(x => x.Id == item.Id).Single();
                        u.RdCenterId = 0;


                        item.RdCenterId = 0;
                        item.RdCenterName = "";
                    }
                    else
                    {
                        item.RdCenterName = r.Name;
                    }
                }
                else
                {
                    item.RdCenterId = 0;
                    item.RdCenterName = "";
                }
            }
            await FillRoleNames(userListDtos);
            return userListDtos;
        }


        public async Task<List<GetPermissionCheckTree>> GetUserPermission(int userId)
        {
            var user = await UserManager.GetUserByIdAsync(userId);
            var permissions = PermissionManager.GetAllPermissions();
            var grantedPermissions = await UserManager.GetGrantedPermissionsAsync(user);
            Dictionary<string, GetPermissionCheckTree> res = new Dictionary<string, GetPermissionCheckTree>();

            foreach (var item in permissions)
            {
                var per = new GetPermissionCheckTree()
                {
                    leaf = false,
                    children = new List<GetPermissionCheckTree>(),
                    @checked = item.IsGrantedByDefault || grantedPermissions.Select(x => x.Name).Any(m => m == item.Name),
                    parentId = item.Parent == null ? "0" : item.Parent.Name,
                    text = item.Name
                };
                res.Add(item.Name, per);
            }

            foreach (var item in res.Values)
            {
                if (res.ContainsKey(item.parentId.ToString()))
                {
                    res[item.parentId.ToString()].children.Add(item);
                }
            }

            var results = res.Values.Where(x => x.parentId == "0").ToList();
            return results;
        }


        public async Task ChangeUserInfo(ChangeUserInfoInPut input)
        {
            var user = UserManager.Users.Where(x => x.Id == input.Id).SingleOrDefault();
            bool valid = await UserManager.CheckPasswordAsync(user, input.OldPassword);
            if (!valid)
            {
                throw new Abp.UI.UserFriendlyException("系统提示", "原密码不匹配");
            }
            // await UserManager.ChangePasswordAsync(user, input.NewPassword);
            var newPass = new PasswordHasher().HashPassword(input.NewPassword);
            user.Password = newPass;
            user.EmailAddress = input.EmailAddress;
            user.Name = input.Name;
            user.Surname = input.Name;
        }


        public async Task<GetUserForEditOutput> Get()
        {
            GetUserForEditOutput output = new GetUserForEditOutput();
            var user = await UserManager.GetUserByIdAsync((long)AbpSession.UserId);

            output.User = user.MapTo<UserEditDto>();
            if (user.BusinessId > 0)
            {
                var _bus = businessRepository.Get(user.BusinessId);
                output.BusinessName = _bus.Name;
            }
            if (user.RdCenterId > 0)
            {
                var _center = rdCenterRepository.Get(user.RdCenterId);
                output.RdCenterName = _center.Name;
            }
            if (user.LaboratoryId > 0)
            {
                var _lab = laboratoryRepository.Get(user.LaboratoryId);
                output.LaboratoryName = _lab.Name;
            }
            return output;
        }


        public void InitPass(int id)
        {
            var user = UserManager.Users.Where(x => x.Id == id).SingleOrDefault();
            user.Password = new PasswordHasher().HashPassword("000000"); ;
        }


        public async Task ImportUser()
        {
            var file = HttpContext.Current.Request.Files[0];

            var users = ExcelHelper.SimpleImport<UserImportInPut>(file.FileName, file.InputStream, 0, 1, 2);

            /*
             * 校验数据：
             * 1、用户名对应的上级存在；
             * 2、邮箱不为空；
             * 3、邮箱的唯一性；
             * 4、当前人员的职位和上级职位必须不一致
             */
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            Dictionary<string, string> dicUserParent = new Dictionary<string, string>();
            Dictionary<string, string> dicEmailUser = new Dictionary<string, string>();
            foreach (var user in users)
            {
                if (string.IsNullOrEmpty(user.Name))
                {
                    continue;
                }
                user.Name = user.Name.Trim();
                if (string.IsNullOrEmpty(user.Position))
                {
                    user.Position = "";
                }
                else
                {
                    user.Position = user.Position.Trim();
                }

                if (string.IsNullOrEmpty(user.Position))
                {
                    sb.AppendLine(string.Format("账号：{0},职位不能为空", user.Name));
                }

                if (dicUserParent.ContainsKey(user.Name))
                {
                    sb.AppendLine(string.Format("账号：{0},重复添加", user.Name));
                    continue;
                }
                user.ParentName = user.ParentName.Trim();
                dicUserParent.Add(user.Name, user.ParentName);
                user.Email = user.Email.Trim();
                if (string.IsNullOrEmpty(user.Email))
                {
                    sb.AppendLine(string.Format("账号：{0},邮箱为空,需要补全", user.Name));
                }
                else
                {
                    if (dicEmailUser.ContainsKey(user.Email))
                    {
                        sb.AppendLine(string.Format("账号：{0}的邮箱{1}有重复", user.Name, user.Email));
                        continue;
                    }
                    dicEmailUser.Add(user.Email, user.Name);
                }



            }


            List<string> parentUserLst = dicUserParent.Values.Distinct().ToList();
            foreach (var parentUser in parentUserLst)
            {
                if (!string.IsNullOrEmpty(parentUser) && !dicUserParent.ContainsKey(parentUser))
                {
                    sb.AppendLine(string.Format("领导：{0},账号不存在", parentUser));
                }
            }

            foreach (var user in users)
            {
                if (string.IsNullOrEmpty(user.Name) || string.IsNullOrEmpty(user.ParentName))
                {
                    continue;
                }

                var parent = users.Where(x => x.Name == user.ParentName).FirstOrDefault();
                if (parent != null && parent.Position.Equals(user.Position))
                {
                    sb.AppendLine(string.Format("领导：{0}和组员{1},的职位不能等同({2})", parent.Name, user.Name, user.Position));
                }
            }
            if (sb.ToString().Length > 0)
            {
                throw new Abp.UI.UserFriendlyException(sb.ToString());
            }



            /*
             * 1、校验研发室有没有，没有则添加
             * 2、添加人员
             * 3、添加人员到组织架构（部门+职位）
             */

            Dictionary<string, Business> dicBusiness = new Dictionary<string, Business>();
            #region 部门-中心-研发室
            var BusinessNames = users.Select(x => x.BusinessName).Distinct().ToList();
            foreach (var businessName in BusinessNames)
            {
                if (string.IsNullOrEmpty(businessName))
                {
                    continue;
                }

                var bus = businessRepository.GetAll().Include("RdCenter").FirstOrDefault(x => x.Name == businessName);
                if (bus == null)
                {
                    bus = new Business()
                    {
                        IsDeleted = false,
                        Name = businessName,
                        Principal = string.Empty,
                        RdCenter = new List<RdCenter>(),
                        Id = 0
                    };
                    int busId = businessRepository.InsertAndGetId(bus);
                    //CurrentUnitOfWork.SaveChanges();
                    bus = businessRepository.GetAll().Include("RdCenter").FirstOrDefault(x => x.Name == businessName);
                }



                var rdcenterNames = users.Where(x => x.BusinessName == businessName).Select(x => x.RdCenterName).Distinct().ToList();
                foreach (var rdcenterName in rdcenterNames)
                {
                    if (string.IsNullOrEmpty(rdcenterName))
                    {
                        continue;
                    }
                    var rd = rdCenterRepository.GetAll().Include("Laboratory").FirstOrDefault(x => x.Name == rdcenterName && x.BusinessId == bus.Id);
                    if (rd == null)
                    {
                        rd = new RdCenter()
                        {
                            IsDeleted = false,
                            Name = rdcenterName,
                            Principal = string.Empty,
                            BusinessId = bus.Id,
                            Laboratory = new List<Laboratory>(),
                            Id = 0
                        };
                        rd.Id = rdCenterRepository.InsertAndGetId(rd);
                        //CurrentUnitOfWork.SaveChanges();
                    }


                    var labNames = users.Where(x => x.RdCenterName == rdcenterName && x.BusinessName == businessName).Select(x => x.LaboratoryName).Distinct().ToList();
                    foreach (var labName in labNames)
                    {
                        if (string.IsNullOrEmpty(labName))
                        {
                            continue;
                        }
                        var lab = laboratoryRepository.FirstOrDefault(x => x.Name == labName && x.RdCenterId == rd.Id);
                        if (lab == null)
                        {
                            lab = new Laboratory()
                            {
                                IsDeleted = false,
                                Name = labName,
                                Principal = string.Empty,
                                RdCenterId = rd.Id,
                                Id = 0
                            };
                            lab.Id = laboratoryRepository.InsertAndGetId(lab);
                            //CurrentUnitOfWork.SaveChanges();
                        }
                        if (!rd.Laboratory.Any(x => x.Id == lab.Id))
                        {
                            rd.Laboratory.Add(lab);
                        }
                    }
                    if (!bus.RdCenter.Any(x => x.Id == rd.Id))
                    {
                        bus.RdCenter.Add(rd);
                    }
                }
                dicBusiness.Add(businessName, bus);
            }

            //-------//以上完成中心的初始化----------------------
            #endregion

            #region 部门-职位
            Dictionary<string, OrganizationUnit> dicOrganization = new Dictionary<string, OrganizationUnit>();
            foreach (var businessName in BusinessNames)
            {
                if (string.IsNullOrEmpty(businessName))
                {
                    continue;
                }

                var org = organizationUnitRepository.GetAll().FirstOrDefault(x => x.DisplayName == businessName);
                if (org == null)
                {
                    org = new OrganizationUnit
                    {
                        IsDeleted = false,
                        DisplayName = businessName,
                        Code = businessName,
                        TenantId = AbpSession.TenantId,
                        Children = new List<OrganizationUnit>(),
                        Id = 0
                    };
                    long orgId = organizationUnitRepository.InsertAndGetId(org);
                    //CurrentUnitOfWork.SaveChanges();
                    org = organizationUnitRepository.GetAll().FirstOrDefault(x => x.Id == orgId);
                }



                var positionNames = users.Where(x => x.BusinessName == businessName).Select(x => x.Position).Distinct().ToList();
                foreach (var positionName in positionNames)
                {
                    if (string.IsNullOrEmpty(positionName))
                    {
                        continue;
                    }
                    var org2 = organizationUnitRepository.GetAll().FirstOrDefault(x => x.DisplayName == positionName && x.ParentId == org.Id);
                    if (org2 == null)
                    {
                        org2 = new OrganizationUnit
                        {
                            IsDeleted = false,
                            DisplayName = positionName,
                            Code = positionName,
                            TenantId = AbpSession.TenantId,
                            ParentId = org.Id,
                            Id = 0
                        };
                        long orgId2 = organizationUnitRepository.InsertAndGetId(org2);
                        //CurrentUnitOfWork.SaveChanges();
                        org2 = organizationUnitRepository.GetAll().FirstOrDefault(x => x.Id == orgId2);
                    }

                    if (!org.Children.Any(x => x.DisplayName == positionName))
                    {
                        org.Children.Add(org2);
                    }

                }
                dicOrganization.Add(businessName, org);
            }
            #endregion


            foreach (var item in users)
            {
                item.QuanCode = "";
                item.QuanId = 0;
                item.UserId = 0;
                item.Role = item.Role.Trim();

                if (UserManager.Users.Any(x => x.Name.Equals(item.Name)))
                {
                    var user = UserManager.Users.Where(x => x.Name == item.Name).FirstOrDefault();
                    item.UserId = user.Id;
                    if (!string.IsNullOrEmpty(item.BusinessName))
                    {
                        var bus = dicBusiness[item.BusinessName];
                        user.BusinessId = bus.Id;

                        if (!string.IsNullOrEmpty(item.RdCenterName))
                        {
                            var rd = bus.RdCenter.Where(x => x.Name == item.RdCenterName).FirstOrDefault();
                            user.RdCenterId = rd.Id;

                            if (!string.IsNullOrEmpty(item.LaboratoryName))
                            {
                                var lab = rd.Laboratory.Where(x => x.Name == item.LaboratoryName).FirstOrDefault();
                                user.LaboratoryId = lab.Id;

                                if (item.IsLaboratoryLeader.Equals("Y"))
                                {
                                    lab.PrincipalId = (int)user.Id;
                                    lab.Principal = user.Name;
                                    laboratoryRepository.Update(lab);
                                }
                            }
                        }

                        var org = dicOrganization[item.BusinessName];
                        if (!string.IsNullOrEmpty(item.Position))
                        {
                            var org2 = org.Children.FirstOrDefault(x => x.DisplayName == item.Position);

                            var userorg = userOrganizationUnitRepository.FirstOrDefault(x => x.OrganizationUnitId == org2.Id && x.UserId == user.Id);
                            if (userorg == null)
                            {
                                userOrganizationUnitRepository.Insert(new UserOrganizationUnit()
                                {
                                    UserId = user.Id,
                                    OrganizationUnitId = org2.Id,
                                    TenantId = AbpSession.TenantId
                                });
                            }
                        }
                        else
                        {
                            var userorg = userOrganizationUnitRepository.FirstOrDefault(x => x.OrganizationUnitId == org.Id && x.UserId == user.Id);
                            if (userorg == null)
                            {
                                userOrganizationUnitRepository.Insert(new UserOrganizationUnit()
                                {
                                    UserId = user.Id,
                                    OrganizationUnitId = org.Id,
                                    TenantId = AbpSession.TenantId
                                });
                            }
                        }


                    }

                    CheckErrors(await UserManager.UpdateAsync(user));




                    continue;
                }
                else
                {
                    var user = new User();
                    user.TenantId = AbpSession.TenantId;
                    user.UserName = item.UserName;
                    user.Name = item.Name;
                    user.Surname = item.Name;
                    user.BusinessId = 0;
                    user.RdCenterId = 0;
                    user.LaboratoryId = 0;
                    user.EmailAddress = item.Email;
                    user.IsActive = true;
                    user.IsEmailConfirmed = false;
                    user.Password = new PasswordHasher().HashPassword("000000");
                    user.ShouldChangePasswordOnNextLogin = false;

                    if (!string.IsNullOrEmpty(item.BusinessName))
                    {
                        var bus = dicBusiness[item.BusinessName];
                        if (bus != null)
                        {
                            user.BusinessId = bus.Id;
                            if (!string.IsNullOrEmpty(item.RdCenterName))
                            {
                                var rd = bus.RdCenter.Where(x => x.Name == item.RdCenterName).FirstOrDefault();
                                if (rd != null)
                                {
                                    user.RdCenterId = rd.Id;
                                    if (!string.IsNullOrEmpty(item.LaboratoryName))
                                    {
                                        var lab = rd.Laboratory.Where(x => x.Name == item.LaboratoryName).FirstOrDefault();
                                        if (lab != null)
                                        {
                                            user.LaboratoryId = lab.Id;
                                            if (item.IsLaboratoryLeader.Equals("Y"))
                                            {
                                                lab.PrincipalId = (int)user.Id;
                                                lab.Principal = user.Name;
                                                laboratoryRepository.Update(lab);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    user.Id = userRepository.InsertAndGetId(user);
                    item.UserId = user.Id;
                    if (!string.IsNullOrEmpty(item.BusinessName))
                    {
                        var org = dicOrganization[item.BusinessName];
                        if (!string.IsNullOrEmpty(item.Position))
                        {
                            var org2 = org.Children.FirstOrDefault(x => x.DisplayName == item.Position);

                            var userorg = userOrganizationUnitRepository.FirstOrDefault(x => x.OrganizationUnitId == org2.Id && x.UserId == user.Id);
                            if (userorg == null)
                            {
                                userOrganizationUnitRepository.Insert(new UserOrganizationUnit()
                                {
                                    UserId = user.Id,
                                    OrganizationUnitId = org2.Id,
                                    TenantId = AbpSession.TenantId
                                });
                            }
                        }
                        else
                        {
                            var userorg = userOrganizationUnitRepository.FirstOrDefault(x => x.OrganizationUnitId == org.Id && x.UserId == user.Id);
                            if (userorg == null)
                            {
                                userOrganizationUnitRepository.Insert(new UserOrganizationUnit()
                                {
                                    UserId = user.Id,
                                    OrganizationUnitId = org.Id,
                                    TenantId = AbpSession.TenantId
                                });
                            }
                        }
                    }


                }

                await CurrentUnitOfWork.SaveChangesAsync();
            }



            InitQuan(users);
            InitRole(users);

        }
        private void InitRole(List<UserImportInPut> users)
        {
            var roles = users.Select(x => x.Role).Distinct().ToList();

            foreach (var roleName in roles)
            {

                var role = _roleManager.Roles.Where(x => x.Name == roleName).SingleOrDefault();
                int roleId = 0;
                if (role == null)
                {
                    roleId = roleRepository.InsertAndGetId(new Role(1, roleName, roleName));
                }
                else
                {
                    roleId = role.Id;
                }

                var itemUsers = users.Where(x => x.Role == roleName).ToList();
                foreach (var item in itemUsers)
                {
                    var user = UserManager.Users.Where(x => x.Id == item.UserId).SingleOrDefault();
                    if (user.Roles == null)
                    {
                        user.Roles = new List<UserRole>();
                    }
                    if (!user.Roles.Any(t => t.RoleId == roleId))
                    {
                        user.Roles.Add(new UserRole(item.UserId, roleId));
                    }
                }

            }


        }

        private void InitQuan(List<UserImportInPut> users)
        {
            List<string> parentNameLst = new List<string> { "" };
            List<string> lastNameLst = new List<string> { };
            do
            {
                lastNameLst = new List<string> { };
                //上级领导
                foreach (var parentName in parentNameLst)
                {
                    int rowIndex = 0;
                    var Childs = users.Where(x => x.ParentName == parentName);
                    var positions = Childs.Select(x => x.Dept.Trim() + x.Position.Trim()).Distinct().ToList();
                    foreach (var position in positions)
                    {
                        string PreCode = "";
                        int parentId = 0;
                        int quanId = 0;
                        if (!string.IsNullOrEmpty(parentName))
                        {
                            PreCode = users.Where(x => x.Name == parentName).FirstOrDefault().QuanCode;
                            parentId = quanRepository.GetAll().Where(x => x.Code == PreCode).FirstOrDefault().Id;
                        }


                        string code = "";


                        do
                        {
                            code = PreCode + rowIndex.ToString("00");
                            if (quanRepository.GetAll().Any(x => x.Code == code && x.Name == position))
                            {
                                quanId = quanRepository.GetAll().Where(x => x.Code == code).FirstOrDefault().Id;
                                break;
                            }
                            else if (quanRepository.GetAll().Any(x => x.Code == code))
                            {
                                rowIndex++;
                            }
                            else
                            {
                                //-------------------------------------------增加新的圈
                                quanId = quanRepository.InsertAndGetId(new Quan()
                                {
                                    Name = position,
                                    Code = code,
                                    IsDeleted = false,
                                    ParentId = parentId
                                });
                                break;
                            }
                        } while (true);



                        var childPosition = Childs.Where(x => x.Dept.Trim() + x.Position.Trim() == position).ToList();
                        foreach (var children in childPosition)
                        {
                            children.QuanCode = code;
                            children.QuanId = quanId;

                            lastNameLst.Add(children.Name);
                        }

                    }


                }
                parentNameLst = lastNameLst;



                if (parentNameLst.Count == 0)
                {
                    break;
                }

            } while (true);


            //给quan增加人员
            var quanLst = quanRepository.GetAll().ToList();
            var existUserQuan = userQuanRepository.GetAll().ToList();
            foreach (var _existItem in existUserQuan)
            {
                userQuanRepository.DeleteAsync(_existItem);
            }
            foreach (var item in quanLst)
            {
                var _userItems = users.Where(x => x.QuanId == item.Id).ToList();
                foreach (var _user in _userItems)
                {
                    userQuanRepository.InsertAsync(new UserQuan()
                    {
                        QuanId = _user.QuanId,
                        UserId = _user.UserId,
                        QuanCode = _user.QuanCode
                    });
                }
            }


        }


        public void GetUserImportTpl()
        {
            ExcelHelper.ResponseFile("User.xlsx", @"App_Data\User.xlsx");
        }


        public async Task SetUserRole(SetUserRoleInPut input)
        {
            var role = _roleManager.Roles.Where(x => x.Id == input.RoleId).SingleOrDefault();
            var user = UserManager.Users.Where(x => x.Id == input.UserId).SingleOrDefault();
            await UserManager.SetRoles(user, role.Name);
        }


        public async Task RemoveRoleUser(RemoveRoleUserInPut input)
        {
            var role = _roleManager.Roles.Where(x => x.Id == input.RoleId).SingleOrDefault();
            await UserManager.RemoveFromRoleAsync(input.UserId, role.Name);
        }
    }
}
